/**
 * 农历与公历互转
 * 		香港天文台: https://www.hko.gov.hk/tc/gts/time/conversion.htm
 * 		公历(阳历)支持: [1900-01-31, 2101-01-28]
 * 		农历(月历)支持: [1900-01-01, 2100-12-29]
 * @param y int|string 年
 * @param m int|string 月  1开始  农历闰月时:+=12
 * @param d int|string 日
 * @param m2s boolean 是否农历取公历  false:公历取农历
 * @return array|null [y,m,d]  null:参数错误
 * 		m: 1开始, 公历取农历->农历闰月时+=12
 */
$.dateMoon = function(y, m, d, m2s=false){
	// 农历数据
	const DATA=[//10=>2进制17位 1:闰月天数(1?30:29)+12:1-12月天数(1?30:29))+4:闰月
		19416,19168,42352,21717,53856,55632,91476,22176,39632,21970,  // 1900-1909
		19168,42422,42192,53840,119381,46400,54944,44450,38320,84343, // 1910-1919
		18800,42160,46261,27216,27968,109396,11104,38256,21234,18800, // 1920-1929
		25958,54432,59984,92821,23248,11104,100067,37600,116951,51536,// 1930-1939
		54432,120998,46416,22176,107956,9680,37584,53938,43344,46423, // 1940-1949
		27808,46416,86869,19872,42416,83315,21168,43432,59728,27296,  // 1950-1959
		44710,43856,19296,43748,42352,21088,62051,55632,23383,22176,  // 1960-1969
		38608,19925,19152,42192,54484,53840,54616,46400,46752,103846, // 1970-1979
		38320,18864,43380,42160,45690,27216,27968,44870,43872,38256,  // 1980-1989
		19189,18800,25776,29859,59984,27480,23232,43872,38613,37600,  // 1990-1999
		51552,55636,54432,55888,30034,22176,43959,9680,37584,51893,   // 2000-2009
		43344,46240,47780,44368,21977,19360,42416,86390,21168,43312,  // 2010-2019
		31060,27296,44368,23378,19296,42726,42208,53856,60005,54576,  // 2020-2029
		23200,30371,38608,19195,19152,42192,118966,53840,54560,56645, // 2030-2039
		46496,22224,21938,18864,42359,42160,43600,111189,27936,44448, // 2040-2049
		84835,37744,18936,18800,25776,92326,59984,27296,108228,43744, // 2050-2059
		37600,53987,51552,54615,54432,55888,23893,22176,42704,21972,  // 2060-2069
		21200,43448,43344,46240,46758,44368,21920,43940,42416,21168,  // 2070-2079
		45683,26928,29495,27296,44368,84821,19296,42352,21732,53600,  // 2080-2089
		59752,54560,55968,92838,22224,19168,43476,41680,53584,62034,  // 2090-2099
		54560, // 2100
	];
	const DAYS_TMP = {}; // 缓存年的天数
	const DAYS = function(idx){ //取农历年天数 idx=年-1900
		if(DAYS_TMP[idx]) return DAYS_TMP[idx];
		let rtn=348, m=DATA[idx], ln=(m&15)!==0;
		for(let i=32768; i>8; i>>=1) (m&i) && rtn++;
		rtn = ln ? rtn+((m&65536)!==0?30:29) : rtn;
		return DAYS_TMP[idx] = rtn;
	};
	const MOON = function(y, m, d){ // 公历取农历:[Y,M,D]
		let c=Date.UTC(y,m-1,d)/864E5+25538, a=0, x;
		if(!c || c<1 || c>73412) return null;
		while(true){ if((x=DAYS(a))>=c) break;  a++; c-=x; }
		x=DATA[a]; let lm=x&15, lx=false, b=1; if(lm) lm++;
		while(true){
			lx=!lx&&(b===lm); let n=x&(lx?65536:(65536>>b));
			n=n?30:29;  if(n>=c) break;  if(!lx) b++;  c-=n;
		}
		return [1900+a, lx?b+11:b, c];
	};
	const TIME = function(y, m, d){ // 农历取公历:时间戳
		y-=1900;  let lx=m>12, x=DATA[y], i;  if(lx) m-=12;
		if(!x || !m || m<1 || m>12 || d<1 || d>30) return null;
		let lm=x&15;  if(lx && m!==lm) return null;
		if(d===30 && (x&(lx?65536:(65536>>m)))===0) return null;
		if(lm && m>lm) d+=(x&65536)===0?29:30;  if(m===lm) m++;
		for(i=1; i<m; i++) d += (x&(65536>>i))===0 ? 29 : 30;
		for(i=0; i<y; i++) d+=DAYS(i); return (d-25538)*864E5;
	};
	$.dateMoon = function(y, m, d, m2s=false){
		y*=1; m*=1; d*=1;  if(!m2s) return MOON(y,m,d);
		let rtn=TIME(y,m,d); if(rtn===null) return null;
		rtn=new Date(rtn);  y=rtn.getUTCFullYear();
		return [y,rtn.getUTCMonth()+1,rtn.getUTCDate()];
	};
	return $.dateMoon(y, m, d, m2s);
};
